package com.silence.springboot.aop;

import com.silence.springboot.common.Result;
import com.silence.springboot.enums.ResultCode;
import com.silence.springboot.exception.ApiException;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.util.StopWatch;

import java.util.Arrays;

/**
 * @author silence
 * @email 792245022@qq.com
 */
@Slf4j
@Aspect
@Component
public class TryCatchAop {

    @Pointcut("execution(* *..controller.*Controller.*(..))")
    public void pointCut() {

    }

    @Around(value = "pointCut()")
    public Object aroundMethod(ProceedingJoinPoint joinPoint) {
        // 获取方法名称和参数
        String methodName = joinPoint.getSignature().getName();
        Object[] args = joinPoint.getArgs();
        log.info("方法名称：{}，参数：{}", methodName, Arrays.toString(args));
        // 计时
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        // 执行目标方法
        Object result;
        try {
            // 调用目标方法
            result = joinPoint.proceed();
            log.info("返回结果：{}", result);
        } catch (ApiException ae) {
            log.warn("ApiException：", ae);
            result = Result.builder()
                    .code(ae.getCode())
                    .msg(ae.getMsg())
                    .build();
        } catch (Exception e) {
            log.error("Exception：", e);
            result = Result.builder()
                    .code(ResultCode.FAILED.getCode())
                    .msg("系统异常，请联系管理员！")
                    .build();
        } catch (Throwable t) {
            log.error("Throwable：", t);
            result = Result.builder()
                    .code(ResultCode.FAILED.getCode())
                    .msg("系统异常，请联系管理员！")
                    .build();
        } finally {
            stopWatch.stop();
            log.info("方法名称：{}，耗时：{}", methodName, stopWatch.getTotalTimeMillis());
        }
        return result;
    }
}
